#!/bin/bash

set -e

# Basic paths
TOP=$(pwd)
BOARD_DIR=${TOP}/device/board/3516cv610
SOC_DIR=${TOP}/device/soc/hisilicon/3516cv610
TOOL_DIR=/opt/linux/x86-arm/arm-v01c02-linux-musleabi-gcc

# Version info
GIT_VERSION=$(git describe --tags --always)
BUILD_TIME=$(date +%Y%m%d%H%M)
VERSION="V1.0.0.${BUILD_TIME}.${GIT_VERSION}"
PRODUCT_NAME="ipc100"

# Output paths
FIRMWARE=${TOP}/out/3516cv610_image
BURN_DIR=${FIRMWARE}/burn
UPGRADE_DIR=${FIRMWARE}/upgrade

# Rootfs structure
ROOTFS=${FIRMWARE}/rootfs
ROOTFS_DIRS=(
    "${ROOTFS}/app"
    "${ROOTFS}/home"
    "${ROOTFS}/mnt"
    "${ROOTFS}/mnt/config"
    "${ROOTFS}/mnt/log"
    "${ROOTFS}/mnt/data"
    "${ROOTFS}/mnt/udisk"
)

# Application paths
APP_ROOT=${FIRMWARE}/app
APP_DIRS=(
    "${APP_ROOT}/bin"
    "${APP_ROOT}/custom"
)

# Print info message with color
function mk_info() {
    echo -e "\033[47;30m[endless]: $*\033[0m"
}

# Initialize build environment
function init_env() {
    mk_info "Initializing build environment..."
    rm -rf ${FIRMWARE}
    mkdir -p ${FIRMWARE} ${BURN_DIR} ${UPGRADE_DIR}
    
    # Create rootfs directories
    for dir in "${ROOTFS_DIRS[@]}"; do
        mkdir -p "$dir"
    done
    
    # Create application directories
    for dir in "${APP_DIRS[@]}"; do
        mkdir -p "$dir"
    done
}

# Pack rootfs
function pack_rootfs() {
    mk_info "=============================================="
    mk_info "Packing rootfs..."
    mk_info "=============================================="
    
    cd ${BOARD_DIR}/rootfs
    tar -xvf rootfs.tar.gz -C ${ROOTFS}
    cd ${ROOTFS}
    
    # Copy overlay files
    cp ${BOARD_DIR}/rootfs/overlay/* ${ROOTFS}/ -rf

    # 删除网络配置
    rm -rf ${ROOTFS}/etc/init.d/S01syslogd
    rm -rf ${ROOTFS}/etc/init.d/S02klogd
    #rm -rf ${ROOTFS}/etc/init.d/S02sysctl
    # rm -rf ${ROOTFS}/etc/init.d/S40network
    rm -rf ${ROOTFS}/etc/init.d/S50telnet
    rm -rf ${ROOTFS}/etc/init.d/S80network
}

# Pack application files
function pack_app() {
    mk_info "=============================================="
    mk_info "Packing application..."
    mk_info "=============================================="
    
    # Create app directories
    for dir in "${APP_DIRS[@]}"; do
        mkdir -p "$dir"
    done
    
    cp ${SOC_DIR}/ko ${APP_ROOT}/ -rf
    cp ${BOARD_DIR}/app/* ${APP_ROOT}/ -rf
    
    if [ -f ${TOP}/out/bin/endless ]; then
        cp ${TOP}/out/bin/endless ${APP_ROOT}/bin -rf
    fi
    
    if [ -d ${TOP}/out/web ]; then
        cp ${TOP}/out/web ${APP_ROOT} -rf
    fi
    
    mk_info "Application packing completed."
}

# Generate rootfs image
function generate_rootfs_image() {
    mk_info "=============================================="
    mk_info "Generating rootfs SquashFS image..."
    mk_info "=============================================="
    
    pushd ${ROOTFS}
    ${TOOL_DIR}/tools/install_dynamic_basic_library.sh ${TOOL_DIR} ${ROOTFS} a7_softfp_neon-vfpv4
    popd
    
    pushd ${FIRMWARE}
    mksquashfs ${ROOTFS} ${FIRMWARE}/rootfs.squashfs -comp gzip -b 128K -noappend
    popd
}

# Generate app image
function generate_app_image() {
    mk_info "=============================================="
    mk_info "Generating app SquashFS image..."
    mk_info "=============================================="
    
    pushd ${FIRMWARE}
    mksquashfs ${APP_ROOT} ${FIRMWARE}/app.squashfs -comp gzip -b 128K -noappend
    popd
}

# Generate final image
function generate_image() {
    mk_info "=============================================="
    mk_info "Generating final image..."
    mk_info "=============================================="
    
    # Copy boot and kernel files
    cp ${BOARD_DIR}/uboot/* ${FIRMWARE}/ -rf
    cp ${BOARD_DIR}/kernel/uImage ${FIRMWARE}/ -rf
    
    # Generate filesystem images
    generate_rootfs_image
    generate_app_image
    
    # Copy files to burn directory with .img suffix
    mv ${FIRMWARE}/boot_image.bin ${BURN_DIR}/uboot.img
    mv ${FIRMWARE}/nand_env.bin ${BURN_DIR}/env.img
    mv ${FIRMWARE}/uImage ${BURN_DIR}/kernel.img
    mv ${FIRMWARE}/rootfs.squashfs ${BURN_DIR}/rootfs.img
    mv ${FIRMWARE}/app.squashfs ${BURN_DIR}/app.img
    mv ${FIRMWARE}/nand_burn_table.xml ${BURN_DIR}/
}

# Generate upgrade package manifest
function generate_manifest() {
    mk_info "Generating upgrade manifest..."
    
    # Get git version info
    GIT_VERSION=$(git describe --tags --always)
    BUILD_TIME=$(date +%Y%m%d%H%M)
    VERSION="V1.0.0.${BUILD_TIME}.${GIT_VERSION}"
    
    # Determine package type
    local PACKAGE_TYPE=${1:-"full"}
    local TYPE_STR="完整"
    case ${PACKAGE_TYPE} in
        "rootfs") TYPE_STR="Rootfs";;
        "app") TYPE_STR="App";;
    esac
    
    mk_info "生成${TYPE_STR}升级包清单..."
    
    # Calculate need_update values based on package type
    local NEED_UPDATE_UBOOT=$([ "$PACKAGE_TYPE" = "full" ] && echo "true" || echo "false")
    local NEED_UPDATE_ENV=$([ "$PACKAGE_TYPE" = "full" ] && echo "true" || echo "false")
    local NEED_UPDATE_KERNEL=$([ "$PACKAGE_TYPE" = "full" ] && echo "true" || echo "false")
    local NEED_UPDATE_ROOTFS=$([ "$PACKAGE_TYPE" = "rootfs" -o "$PACKAGE_TYPE" = "full" ] && echo "true" || echo "false")
    local NEED_UPDATE_APP=$([ "$PACKAGE_TYPE" = "app" -o "$PACKAGE_TYPE" = "full" ] && echo "true" || echo "false")
    
    # Generate manifest with need_update control
	cat > ${UPGRADE_DIR}/manifest.json << EOF
{
    "product": {
        "name": "ipc100",
        "hardware": "1.0.0"
    },
    "version": {
        "to": "${VERSION}"
    },
    "type": "${PACKAGE_TYPE}",
    "files": [
        {
            "name": "uboot.img",
            "partition": "/dev/mtd0",
            "offset": "0x0",
            "size": $(stat -c%s ${BURN_DIR}/uboot.img),
            "verify": true,
            "need_update": ${NEED_UPDATE_UBOOT},
            "hash": "sha256:$(sha256sum ${BURN_DIR}/uboot.img | cut -d' ' -f1)"
        },
        {
            "name": "env.img",
            "partition": "/dev/mtd1",
            "offset": "0x0",
            "size": $(stat -c%s ${BURN_DIR}/env.img),
            "need_update": ${NEED_UPDATE_ENV},
            "verify": true,
            "hash": "sha256:$(sha256sum ${BURN_DIR}/env.img | cut -d' ' -f1)"
        },
        {
            "name": "kernel.img",
            "partition": "/dev/mtd2",
            "offset": "0x0",
            "size": $(stat -c%s ${BURN_DIR}/kernel.img),
            "need_update": ${NEED_UPDATE_KERNEL},
            "verify": true,
            "hash": "sha256:$(sha256sum ${BURN_DIR}/kernel.img | cut -d' ' -f1)"
        },
        {
            "name": "rootfs.img",
            "partition": "/dev/mtd3",
            "offset": "0x0",
            "size": $(stat -c%s ${BURN_DIR}/rootfs.img),
            "need_update": ${NEED_UPDATE_ROOTFS},
            "verify": true,
            "hash": "sha256:$(sha256sum ${BURN_DIR}/rootfs.img | cut -d' ' -f1)"
        },
        {
            "name": "app.img",
            "partition": "/dev/mtd4",
            "offset": "0x0",
            "size": $(stat -c%s ${BURN_DIR}/app.img),
            "need_update": ${NEED_UPDATE_APP},
            "verify": true,
            "hash": "sha256:$(sha256sum ${BURN_DIR}/app.img | cut -d' ' -f1)"
        }
    ],
    "compatibility": {
        "min_version": "V1.0.0",
        "max_version": "V1.9.9"
    }
}
EOF
}

# Generate upgrade package
function generate_upgrade_package() {
    mk_info "=============================================="
    mk_info "Generating upgrade package..."
    mk_info "=============================================="
    
    # Create upgrade directory
    mkdir -p ${UPGRADE_DIR}
    
    # Get package type from argument
    local PACKAGE_TYPE=${1:-"full"}
    local TYPE_STR="完整"
    case ${PACKAGE_TYPE} in
        "rootfs") TYPE_STR="Rootfs";;
        "app") TYPE_STR="App";;
    esac
    
    mk_info "生成${TYPE_STR}升级包..."
    
    # Create a temporary directory for package files
    local TEMP_DIR=${UPGRADE_DIR}/temp_${PACKAGE_TYPE}
    rm -rf ${TEMP_DIR}
    mkdir -p ${TEMP_DIR}
    
    # Clean up previous files
    rm -f ${UPGRADE_DIR}/*.img
    
    case ${PACKAGE_TYPE} in
        "rootfs")
            # Copy only rootfs image for rootfs upgrade
            cp ${BURN_DIR}/rootfs.img ${TEMP_DIR}/
        ;;
        "app")
            # Copy only app image for app upgrade
            cp ${BURN_DIR}/app.img ${TEMP_DIR}/
        ;;
        "full")
            # Copy all images for full upgrade
            cp ${BURN_DIR}/uboot.img ${TEMP_DIR}/
            cp ${BURN_DIR}/kernel.img ${TEMP_DIR}/
            cp ${BURN_DIR}/rootfs.img ${TEMP_DIR}/
            cp ${BURN_DIR}/app.img ${TEMP_DIR}/
            cp ${BURN_DIR}/env.img ${TEMP_DIR}/
        ;;
    esac
    
    # Generate manifest
    generate_manifest ${PACKAGE_TYPE}
    cp ${UPGRADE_DIR}/manifest.json ${TEMP_DIR}/
    
    # Create upgrade package
    GIT_VERSION=$(git describe --tags --always)
    BUILD_TIME=$(date +%Y%m%d%H%M)
    UPGRADE_PACKAGE="ipc100_V1.0.0.${BUILD_TIME}.${GIT_VERSION}_${PACKAGE_TYPE}.bin"
    
    cd ${TEMP_DIR}
    zip -r ../${UPGRADE_PACKAGE} ./*
    cd - >/dev/null
    
    # Clean up temporary directory
    rm -rf ${TEMP_DIR}
    
    mk_info "Generated upgrade package: ${UPGRADE_DIR}/${UPGRADE_PACKAGE}"
}

# Main process
function main() {
    init_env
    pack_rootfs
    pack_app
    generate_image
    
    # Generate all types of upgrade packages
    generate_upgrade_package "rootfs"
    generate_upgrade_package "app"
    generate_upgrade_package "full"
    
    mk_info "Build Success !!! ^_^"
}

main
